package com.xcj.springai.mapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xcj.springai.entity.ChatConversationEntity;
import com.xcj.springai.entity.ChatMessageEntity;
import com.xcj.springai.service.ChatConversationService;
import com.xcj.springai.service.ChatMessageService;
import com.xcj.springai.utils.MessageConverter;
import jakarta.annotation.Resource;
import lombok.Builder;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * MySqlChatMemoryRepository 实现了 Spring AI 的 ChatMemoryRepository 接口，
 * 用于管理和持久化聊天会话的历史消息和会话信息。
 * 具体实现为基于 MySQL 数据库，通过 MyBatis-Plus 调用 Service 层进行数据访问。
 *
 * 作用：
 *  - 加载指定会话的消息历史
 *  - 保存新的聊天消息及会话信息
 *  - 删除指定会话及其消息记录
 *
 * 该类被 Spring 容器托管 (@Component)，并通过依赖注入获取 ChatMessageService 和 ChatConversationService，
 * 用于操作数据库中的聊天消息和会话表。
 */
@Component
@Builder
public class MySqlChatMemoryRepository implements ChatMemoryRepository {

    // 注入聊天消息服务，用于操作聊天消息表（增删改查）
    @Resource
    private ChatMessageService chatMessageService;

    // 注入聊天会话服务，用于操作聊天会话表（增删改查）
    @Resource
    private ChatConversationService chatConversationService;

    /**
     * 获取所有存在的聊天会话ID列表
     * 供框架用于获取所有会话，可能用于恢复或显示会话列表
     *
     * @return 会话ID字符串列表
     */
    @Override
    public List<String> findConversationIds() {
        return chatConversationService.lambdaQuery()
                .select(ChatConversationEntity::getId)
                .list()
                .stream()
                .map(ChatConversationEntity::getId)
                .toList();
    }

    /**
     * 根据会话ID加载该会话的聊天消息列表
     *
     * @param conversationId 格式为 "会话ID:用户ID"
     * @return 该会话对应的聊天消息列表（转换成 Spring AI 的 Message 类型）
     */
    @Override
    public List<Message> findByConversationId(String conversationId) {
        // 会话ID拆分为两个部分，方便查数据库
        String[] split = conversationId.split(":");
        List<Message> list = chatMessageService.lambdaQuery()
                .eq(ChatMessageEntity::getConversationId, split[0])  // 会话ID匹配
                .eq(ChatMessageEntity::getUserId, split[1])
                .orderByAsc(ChatMessageEntity::getCreateTime)
                .list()
                .stream()
                .map(MessageConverter::toMessage)  // 转换为聊天框架消息对象
                .toList();
        return list;
    }

    /**
     * 保存一批聊天消息，同时根据第一条用户消息创建或更新聊天会话信息
     *
     * @param conversationId 格式为 "会话ID:用户ID"
     * @param messages 聊天消息列表（Spring AI 的 Message 类型）
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveAll(String conversationId, List<Message> messages) {
        String[] split = conversationId.split(":");

        // 将聊天消息转换成数据库实体对象，并绑定会话ID和用户ID
        List<ChatMessageEntity> chatMessageList = messages.stream()
//                .map(message -> MessageConverter.toChatMessage(message, split[0],split[0], split[1]))
                .map(message -> MessageConverter.toChatMessage(message, split[0],split[0]))
                .toList();

        // 找出第一条用户消息，用于创建会话标题等信息
        Optional<Message> firstUserMessage = messages.stream()
                .filter(message -> message.getMessageType() == MessageType.USER)
                .findFirst();

        firstUserMessage.ifPresent(message -> {
            // 如果当前会话不存在，则创建新的会话记录
            boolean exists = chatConversationService.exists(
                    new LambdaQueryWrapper<ChatConversationEntity>()
                            .eq(ChatConversationEntity::getId, split[0])
                            .eq(ChatConversationEntity::getUserId, split[1])
            );
            if (!exists) {
                ChatConversationEntity chatConversation = new ChatConversationEntity();
                chatConversation.setId(split[0]);
                chatConversation.setUserId(split[1]);
                chatConversation.setTitle(messages.get(0).getText()); // 用首条消息文本作为会话标题
                chatConversation.setCreateTime(new Date());
                chatConversationService.saveOrUpdate(chatConversation);
            }
        });

        // 删除数据库中原有的该会话所有消息（避免重复）
        chatMessageService.remove(new LambdaQueryWrapper<ChatMessageEntity>()
                .eq(ChatMessageEntity::getConversationId, split[0])
                .eq(ChatMessageEntity::getUserId, split[1]));

        // 批量保存当前最新的聊天消息列表
        chatMessageService.saveOrUpdateBatch(chatMessageList);
    }

    /**
     * 删除指定会话及其所有消息
     *
     * @param conversationId 格式为 "会话ID:用户ID"
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByConversationId(String conversationId) {
        String[] split = conversationId.split(":");
        // 删除聊天会话记录
        chatConversationService.remove(new LambdaQueryWrapper<ChatConversationEntity>()
                .eq(ChatConversationEntity::getId, split[0])
                .eq(ChatConversationEntity::getUserId, split[1]));

        // 删除该会话下的所有聊天消息
        chatMessageService.remove(new LambdaQueryWrapper<ChatMessageEntity>()
                .eq(ChatMessageEntity::getConversationId, split[0])
                .eq(ChatMessageEntity::getUserId, split[1]));
    }
}
